package com.eesujie.xcs.common;


import com.eesujie.xcs.entity.vo.UserVO;
import com.eesujie.xcs.util.JsonUtils;
import com.eesujie.xcs.util.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Component
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {

    private JwtUtils jwtUtils;

    @Override
    public boolean preHandle(@NonNull HttpServletRequest request,
                             @NonNull HttpServletResponse response,
                             @NonNull Object handler)
            throws Exception {
        String jwt = request.getHeader(jwtUtils.getHeader());
        Claims claims = jwtUtils.getClaimsByToken(jwt);
        if (claims == null || jwtUtils.isTokenExpired(claims)) return authFailureHandle(response);
        UserContext.setUserVO(JsonUtils.toEntity(claims.getSubject(), UserVO.class));
        return true;
    }

    private boolean authFailureHandle(HttpServletResponse response) throws IOException {
        log.info("jwt认证失败");
        responseResult(response, Result.failure(Result.ResultStatusEnum.UNAUTHORIZED));
        return false;
    }


    private static void responseResult(HttpServletResponse response, Result result) throws IOException {
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setStatus(result.getCode());
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(JsonUtils.toJson(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }

    @Override
    public void afterCompletion(@NonNull HttpServletRequest request,
                                @NonNull HttpServletResponse response,
                                @NonNull Object handler, Exception ex) throws Exception {
        UserContext.remove();
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }


    @Autowired
    public void setJwtUtils(JwtUtils jwtUtils) {
        this.jwtUtils = jwtUtils;
    }
}
